package org.cxa.rpc.cloud.configurationConsole;

import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;

import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;

import javax.swing.JLabel;

import org.cxa.misc.NumberUtils;
import org.cxa.rpc.cloud.client.TransientDevice;
import org.cxa.rpc.messages.ResponseRpcMessage;
import org.cxa.rpc.session.SessionManager.AsynchronousRequestListener;


public class FooterPanel extends JPanel
{
	private static final long serialVersionUID = 9145988119368862528L;
	private static final String NUM_CONNS_FORMAT_STR = "Num conns/proxies: %s";
	private static final String MEM_STATS_FORMAT_STR = "Memory usage: %s";
	private static final int UPDATE_PERIOD_MS = 1000;
	
	
	private final JLabel lblNumConnsProxies;
	private final JLabel lblMemoryStats;
	
	private final TransientDevice tDev;
	
	
	/**
	 * Create the panel.
	 */
	public FooterPanel(TransientDevice tDevIn)
	{
		this.tDev = tDevIn;
		
		setLayout(new FormLayout(new ColumnSpec[] {
				FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC,
				FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC,
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("default:grow"),},
			new RowSpec[] {
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,}));
		
		lblNumConnsProxies = new JLabel(String.format(NUM_CONNS_FORMAT_STR, "<??>"));
		lblNumConnsProxies.setToolTipText("# iob clients / # jetty connections");
		add(lblNumConnsProxies, "2, 2");
		
		lblMemoryStats = new JLabel(String.format(MEM_STATS_FORMAT_STR, "<??>"));
		lblMemoryStats.setToolTipText("used(MB) / free(MB) / total(MB)");
		add(lblMemoryStats, "4, 2, left, default");
		
		JLabel lblError = new JLabel();
		add(lblError, "6, 2, left, default");
		
		new Timer().schedule(new TimerTask()
		{
			@Override
			public void run()
			{
				if( tDev.isConnected() )
				{
					updateNumConnDevs();
					updateMemoryStats();
				}
			}
		}, UPDATE_PERIOD_MS, UPDATE_PERIOD_MS);
	}
	
	
	private void updateNumConnDevs()
	{
		tDev.sendRequest("/sys", "getNumConnectedDevices", new AsynchronousRequestListener()
		{
			@Override
			public void onResponseReceived(ResponseRpcMessage msgIn)
			{
				if( msgIn.getWasSuccessful() )
				{
					@SuppressWarnings("unchecked")
					Map<String, Number> connValues = (Map<String, Number>) msgIn.getReturnValue(Map.class);
					if( connValues == null ) return;
					
					Integer iob_connClients = (Integer) NumberUtils.castToClass_strict(connValues.get("iob_connClients"), Integer.class);
					if( iob_connClients == null ) return;
					
					Integer jetty_openConns = (Integer) NumberUtils.castToClass_strict(connValues.get("jetty_openConns"), Integer.class);
					if( jetty_openConns == null ) return;
					
					lblNumConnsProxies.setText(String.format(NUM_CONNS_FORMAT_STR, String.format("%d / %d", iob_connClients, jetty_openConns)));
				}	
			}
		});
	}
	
	
	private void updateMemoryStats()
	{
		tDev.sendRequest("/sys", "getMemoryStats", new AsynchronousRequestListener()
		{
			@Override
			public void onResponseReceived(ResponseRpcMessage msgIn)
			{
				if( msgIn.getWasSuccessful() )
				{
					@SuppressWarnings("unchecked")
					Map<String, Number> memStats = (Map<String, Number>) msgIn.getReturnValue(Map.class);
					if( memStats == null ) return;
					
					Long used_MB = (Long) NumberUtils.castToClass_strict(memStats.get("used_MB"), Long.class);
					if( used_MB == null ) return;
					
					Long free_MB = (Long) NumberUtils.castToClass_strict(memStats.get("free_MB"), Long.class);
					if( free_MB == null ) return;
					
					Long total_MB = (Long) NumberUtils.castToClass_strict(memStats.get("total_MB"), Long.class);
					if( total_MB == null ) return;
					
					lblMemoryStats.setText(String.format(MEM_STATS_FORMAT_STR, String.format("%d / %d / %d", used_MB, free_MB, total_MB)));
				}	
			}
		});
	}
}
